package com.atguigu.gmall.item.controller;

import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.item.service.LockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lhh
 * @ClassName LockController
 * @date 2022 2022/12/8
 */

@RestController
public class LockController {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    LockService lockService;

    int i=1;

    CountDownLatch latch =new CountDownLatch(10000);

    ReentrantLock lock=new ReentrantLock();
    /**
     * 并发情况操作共享请求会发生安全问题
     *  发送1w请求
     * 无锁 单实例 289
     * 本地锁 单实例 10000 在分布式就不能保证线程安全
     * 本地所 集群  4523
     *
     * @return
     */

    @GetMapping("/inner")
    public Result inner() throws InterruptedException {
        //分布式锁 利用setnx ，redis在没有这个key的时候插入key，有就没操作

        //加锁
        String s=lockService.lock(); //自旋锁
        String num = redisTemplate.opsForValue().get("num");
            //num+1操作
        num=Integer.parseInt(num) + 1+ "";
            ///存入num
            redisTemplate.opsForValue().set("num",num);

        //解锁
        lockService.unlock(s);
        return  Result.ok();
    }



    public Result getNumber(){
//        i++;
//        latch.countDown();
//        ReentrantLock lock = new ReentrantLock();
//
        lock.lock();
        try {
            //从远程获取一个num
            String num = redisTemplate.opsForValue().get("num");
            //num+1操作
            num=Integer.parseInt(num) + 1+ "";
            ///存入num
            redisTemplate.opsForValue().set("num",num);
        }finally {
            lock.unlock();
        }
        return  Result.ok();
    }

    @GetMapping("/result")
    public Result result() throws InterruptedException {
        //latch.await();
        return Result.ok(i);
    }
}
